package com.tmindtech.api.enterprise.service

import com.google.common.base.Strings
import com.tmindtech.api.dept.db.DeptMapper
import com.tmindtech.api.dept.model.Department
import com.tmindtech.api.enterprise.db.*
import com.tmindtech.api.enterprise.model.*
import com.tmindtech.api.justice.db.JusticeStaffMapper
import com.tmindtech.api.justice.model.JusticeStaff
import com.tmindtech.api.justice.model.StaffType
import com.tmindtech.api.utils.importCsv
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import java.io.InputStream
import java.text.SimpleDateFormat
import java.util.regex.Pattern

/**
 * Created by RexQian on 2017/11/22.
 */
@Component
class EnterpriseCsvImport {

    @Autowired
    lateinit var deptMapper: DeptMapper

    @Autowired
    lateinit var enterpriseMapper: EnterpriseMapper

    @Autowired
    lateinit var enterpriseLocationMapper: EnterpriseLocationMapper

    @Autowired
    lateinit var enterpriseCheckRecordMapper: EnterpriseCheckRecordMapper

    @Autowired
    lateinit var legalEntityMapper: LegalEntityMapper

    @Autowired
    lateinit var sunKitchenMapper: SunKitchenMapper

    @Autowired
    lateinit var staffCheckMapMapper: StaffCheckMapMapper

    @Autowired
    lateinit var staffMapper: JusticeStaffMapper

    //   	内部序号	企业名称	注册号	注册资本	经营地址	经营范围	法定代表人	成立日期	企业类型	登记机关	管辖单位
    // 1	3.31024E+15	**	3.31025E+14	1.5	仙居县福应街道后溪路94－4号	服装零售。	陈金伟	2009/7/23	个体户	仙居县市场监督管理局	福应所
    @Transactional
    fun importEnterpriseCsv(inputStream: InputStream) {
        val deptList = deptMapper.selectAll()
        importCsv(inputStream) { line ->
            val item = line2Enterprise(line, deptList)
            enterpriseMapper.insertSelective(item)
            return@importCsv true
        }
    }

    private fun line2Enterprise(line: Array<String>, deptList: List<Department>): Enterprise {
        val item = Enterprise()
        item.code = line[1].trim()
        item.name = if (line[2].trim().startsWith("*")) line[7].trim() else line[2].trim()
        item.regCode = line[3].trim()
        item.fund = if (Strings.isNullOrEmpty(line[4].trim())) 0 else (line[4].trim().toFloat() * 10000).toInt()
        item.address = line[5].trim()
        item.scope = line[6].trim()
        val dateFormat = SimpleDateFormat("yyyy-MM-dd")
        item.regDate = dateFormat.parse(line[8].trim())
        item.type = line[9].trim()
        item.regGov = line[10].trim()
        item.manageGovId = string2GovId(line[11].trim(), deptList)
        return item
    }

    private fun string2GovId(str: String, deptList: List<Department>): Long? {
        return deptList.firstOrNull { it.name.equals(str) }
                ?.id
                ?: 0
    }

    /**
     * QYBH	MODULE_ID	LONGITUDE	LATITUDE	COMPANY
     * 3.31024E+15	4028b88150f98f170150f9a22afc0001	120.729492	28.844231	仙居县金山宾馆
     */
    @Transactional
    fun importEnterpriseLocationCsv(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val item = line2Location(line) ?: return@importCsv false
            enterpriseLocationMapper.insertSelective(item)
            return@importCsv true
        }
    }

    private fun line2Location(line: Array<String>): EnterpriseLocation? {
        val enterprise = enterpriseMapper.selectOne(Enterprise(code = line[0].trim())) ?: return null
        val item = EnterpriseLocation()
        item.id = enterprise.id
        if (line[2].isBlank() || line[3].isBlank()) return null
        item.longitude = line[2].trim().toDoubleOrNull()
        item.latitude = line[3].trim().toDoubleOrNull()
        return item
    }

    /**
     *  ID	QYMC	QYBH	MOULEID	CONTACTPERSON	RESULT	RESULTDATE	PERSONCODE	PERSONNAME	PERSONPHONE	MARK	LONGITUDE	LATITUDE	ADDRESS
     *  1	8a9881da5f967b18015fbd84a6c85b64	仙居县手心的暖奶茶店	3.31024E+15	cyqy	应俊杰	查无下落	2017/11/15 10:31	wangjunbiao,chenlijuan-331024	王俊飚,陈丽娟	13566692665	7	120.740067	28.843474	浙江省台州市仙居县穿城南路靠近仙居县统计局
     */
    @Transactional
    fun importEnterpriseCheckRecordCsv(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val item = line2CheckRecord(line) ?: return@importCsv false
            enterpriseCheckRecordMapper.insertSelective(item)
            item.staffs?.let { addCheckStaffMap(item.id, item.staffs!!) }
            return@importCsv true
        }
    }

    private fun addCheckStaffMap(checkId: Long, staffs: List<String>) {
        staffs.forEach { i ->
            val list = staffMapper.select(JusticeStaff(name = i, type = StaffType.Justice.value))
            if (list.size != 1) return@forEach
            staffCheckMapMapper.insertSelective(StaffCheckMap(checkId, list[0].id))
        }
    }

    private fun line2CheckRecord(line: Array<String>): EnterpriseCheckRecord? {
        val item = EnterpriseCheckRecord()
        val codeInLine = line[3].trim()
        val enterprise = enterpriseMapper.selectOne(Enterprise(code = codeInLine)) ?: return null
        item.enterpriseId = enterprise.id
        item.contact = line[5].trim()
        item.resultMsg = line[6].trim()
        item.resultType = resultMsgToType(line[6].trim())
        val dateFormat = SimpleDateFormat("yyyy/MM/dd HH:mm")
        item.resultDate = dateFormat.parse(line[7].trim())
        item.staffs = line[9].trim().split(",").toList()
        item.staffPhone = line[10].trim()
        item.longitude = line[12].toDoubleOrNull() ?: return null
        item.latitude = line[13].toDoubleOrNull() ?: return null
        item.address = line[14].trim()
        return item
    }

    private fun resultMsgToType(msg: String): Int {
        if (msg == "查无下落") {
            return CheckResultType.FAIL.value
        }
        if (msg.contains("项正常")) {
            val pattern = Pattern.compile("(\\d*)\\D*(\\d*).*")
            val matcher = pattern.matcher(msg)
            if (matcher.find()) {
                val normalCount = matcher.group(1)
                val totalCount = matcher.group(2)
                if (normalCount != totalCount) {
                    return CheckResultType.FAIL.value
                }
            }
        }
        return CheckResultType.PASS.value
    }

    @Transactional
    fun importLegalEntity(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val item = line2LegalEntity(line) ?: return@importCsv false
            legalEntityMapper.insertSelective(item)
            return@importCsv true
        }
    }

    /**
     * ,内部序号,姓名,住址,证件类型,证件号码
     * 1,3310243062420273,应良月,仙居县双庙乡解放村大园1-5号,居民身份证,332624194909295577
     */
    private fun line2LegalEntity(line: Array<String>): LegalEntity? {
        val enterprise = enterpriseMapper.selectOne(Enterprise(code = line[1].trim())) ?: return null
        val item = LegalEntity()
        item.id = enterprise.id
        item.name = line[2].trim()
        item.address = line[3].trim()
        item.idType = line[4].trim()
        item.idCard = line[5].trim()
        return item
    }

    @Autowired
    lateinit var produceDataMapper: ProduceDataMapper

    @Transactional
    fun importProduceData(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val item = line2ProduceData(line) ?: return@importCsv false
            produceDataMapper.insertSelective(item)
            return@importCsv true
        }
    }

    private fun line2ProduceData(line: Array<String>): ProduceData? {
        val item = ProduceData()
        item.enterpriseId = enterpriseMapper.selectOne(Enterprise(name = line[0].trim()))?.id ?: return null
        item.name = line[1].trim()
        item.batchNumber = line[2].trim()
        val dateFormat = SimpleDateFormat("yyyy-MM-dd")
        item.produceDate = dateFormat.parse(line[3].trim())
        item.count = line[4].trim().toIntOrNull() ?: return null
        return item
    }

    @Transactional
    fun importSunKitchen(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val item = line2SunKitchen(line) ?: return@importCsv false
            sunKitchenMapper.insertSelective(item)
            return@importCsv true
        }
    }

    private fun line2SunKitchen(line: Array<String>): SunKitchen? {
        val item = SunKitchen()
        item.enterpriseId = enterpriseMapper.selectOne(Enterprise(regCode = line[4].trim()))?.id ?: return null
        item.name = line[1].trim()
        item.cDeviceIndexCode = line[0].trim()
        item.cameraCode = line[2].trim()
        return item
    }

    @Autowired
    lateinit var productCheckMapper: ProductCheckMapper

    @Transactional
    fun importProductCheck(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val item = line2ProductCheck(line) ?: return@importCsv false
            productCheckMapper.insertSelective(item)
            return@importCsv true
        }
    }

    private fun line2ProductCheck(line: Array<String>): ProductCheck? {
        val item = ProductCheck()
        item.enterpriseId = enterpriseMapper.selectOne(Enterprise(name = line[1].trim()))?.id ?: return null
        item.checkDate = SimpleDateFormat("dd.MM.yyyy").parse(line[24].trim())
        item.sampleName = line[9].trim()
        item.projectName = line[51].trim()
        item.checkResult = str2CheckResult(line[53].trim()).value
        return item
    }

    private fun str2CheckResult(str: String): CheckResult {
        return when (str) {
            "合格项" -> CheckResult.PASS
            "不合格项", "问题项" -> CheckResult.FAIL
            else -> CheckResult.NOT_CHECK
        }
    }

    @Transactional
    fun importEnterpriseCategory(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val key: String = if (line[2].trim().startsWith("*")) {
                line[3].trim()
            } else {
                line[2].trim()
            }
            val item: Enterprise
            val list = enterpriseMapper.select(Enterprise(name = key))
            item = when {
                list.size == 0 -> return@importCsv false
                list.size == 1 -> list[0]
                else -> list.firstOrNull { i -> i.address == line[20].trim() } ?: return@importCsv false
            }
            val updateItem = Enterprise()
            updateItem.id = item.id
            updateItem.category = line[8].trim()
            enterpriseMapper.updateByPrimaryKeySelective(updateItem)
            return@importCsv true
        }
    }
}
